package com.cskaoyan.service.wx;

import com.cskaoyan.dao.usercoupon.UserCouponDao;
import com.cskaoyan.dao.wx.WxOrderDao;
import com.cskaoyan.dao.wx.adress.WXAddressDao;
import com.cskaoyan.dao.wx.cart.WXCartMapper;
import com.cskaoyan.model.BaseParam;
import com.cskaoyan.model.admin.goodsbean.Comment;
import com.cskaoyan.model.admin.goodsbean.OrderGoods;
import com.cskaoyan.model.admin.marketbeans.pojo.MarketAftersale;
import com.cskaoyan.model.admin.marketbeans.pojo.MarketOrder;
import com.cskaoyan.model.realm.WxLoginUserData;
import com.cskaoyan.model.wx.aftersale.WxAftersaleListVo;
import com.cskaoyan.model.wx.aftersale.WxAftersaleVo;
import com.cskaoyan.model.wx.cart.Cart;
import com.cskaoyan.model.wx.order.bo.CommentSession;
import com.cskaoyan.model.wx.order.bo.WxOrderSubmitBo;
import com.cskaoyan.model.wx.order.vo.*;
import com.cskaoyan.model.wx.wxadressbean.vo.WXAddressDetailVo;
import com.cskaoyan.utils.BeanCreateUtils;
import com.cskaoyan.utils.DateUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.MathContext;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @package: com.cskaoyan.service.wx
 * @Description: 微信小程序订单模块
 * @author: 北青
 * @date: 2022/1/10 15:10
 */
@Service
public class WxOrderServiceImpl implements WxOrderService {

    @Autowired
    WxOrderDao wxOrderDao;
    @Autowired
    WXAddressDao wxAddressMapper;
    @Autowired
    WXCartMapper wxCartMapper;

    @Autowired
    UserCouponDao userCouponDao;
    /**
     * 显示订单详情
     * @param baseParam
     * @param showType
     * @return
     */
    @Override
    public WxOrderListInfoVo getWxOrderListInfo(BaseParam baseParam, Integer showType) {

        //分页
        Integer page = baseParam.getPage();
        Integer limit = baseParam.getLimit();
        PageHelper.startPage(page, limit);
        int orderStatus = 0;
        //通过showType数值确定订单状态
       if (showType == 1){
           orderStatus = 101;
       } else if(showType == 2){
           orderStatus = 201;
       } else if (showType == 3){
           orderStatus = 301;
       } else if(showType == 4){
           orderStatus = 401;
       }

        //获取用户信息
        WxLoginUserData principal = (WxLoginUserData) SecurityUtils.getSubject().getPrincipal();
        Integer userId = principal.getId();

        this.updateOrderValues(userId); //修改过期未付款订单和未评论订单状态

        //查询数据库
        List<WxOrderVo> list = wxOrderDao.getWxOrderList(userId, orderStatus);

        //遍历订单,查询订单当中的商品详情
        for (WxOrderVo wxOrderVo : list) {
            List<WxOrderGoodsVo> goodsList = wxOrderDao.getWxOrderGoodsList(wxOrderVo.getId());
            HandleOptionVo handleOptionVo = wxOrderDao.getHandleOption(wxOrderVo.getOrderStatus());
            wxOrderVo.setGoodsList(goodsList);
            wxOrderVo.setHandleOption(handleOptionVo);
        }
        //获取分页信息
        PageInfo<WxOrderVo> pageInfo = new PageInfo<>(list);
        //封装返回参数
        WxOrderListInfoVo wxOrderListInfoVo = new WxOrderListInfoVo();
        wxOrderListInfoVo.setList(list);
        wxOrderListInfoVo.setLimit(limit);
        wxOrderListInfoVo.setPage(page);
        wxOrderListInfoVo.setTotal((int) pageInfo.getTotal());
        wxOrderListInfoVo.setPages(pageInfo.getPages());
        //返回结果
        return wxOrderListInfoVo;
    }

    /**
     * 修改过期未付款订单和未评论订单状态
     */
    private void updateOrderValues(Integer userId) {
        //修改未付款的过期订单状态为103,系统取消
        Integer orderStatus = 103;
        //当前时间
        String time = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(System.currentTimeMillis());
        wxOrderDao.changeOrderStatusByUserId(orderStatus, time, userId);

        //TODO 这里要获取所有过期的订单ID
        //List<WxOrderDetailGoodsVo> orderGoods = this.getWxOrderDetailInfo(orderId).getOrderGoods();

        //修改所有未评价的商品中更新时间超过7天的商品可评价状态为-1
        String endtime = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(System.currentTimeMillis() - 604800000L );
       wxOrderDao.updateOrderGoodsComment(endtime);
    }


    /**
     * 小程序显示订单详情
     * @param orderId
     * @return
     */
    @Override
    public WxOrderDetailInfoVo getWxOrderDetailInfo(Integer orderId) {
        WxOrderDetailInfoVo wxOrderDetailInfoVo = new WxOrderDetailInfoVo();
        WxOrderDetailVo wxOrderDetailVo = wxOrderDao.getOrderDetailByOrderId(orderId);
        List<WxOrderDetailGoodsVo> goodsList = wxOrderDao.getOrderDetaiGoodsByOrderId(orderId);
        HandleOptionVo handleOptionVo = wxOrderDao.getHandleOption(wxOrderDetailVo.getOrderStatus());
        //TODO
        wxOrderDetailInfoVo.setExpressInfo(new LinkedList<ExpressInfoVo>());
        wxOrderDetailVo.setHandleOption(handleOptionVo);
        wxOrderDetailInfoVo.setOrderInfo(wxOrderDetailVo);
        wxOrderDetailInfoVo.setOrderGoods(goodsList);
        return wxOrderDetailInfoVo;
    }

    /**
     * 取消订单
     * @param orderId
     */
    @Override
    public void cancelOrder(Integer orderId) {
        //取消订单之后的状态码
        Integer orderStatus = 102;
        wxOrderDao.changeOrderStatus(orderStatus, orderId);
    }

    /**
     * 申请退款
     * @param orderId
     */
    @Override
    public void refund(Integer orderId) {
        Integer orderStatus = 202;
        Integer aftersaleStatus = 1; //订单售后状态,1表示用户已申请
        wxOrderDao.changeOrderStatusAndAftersaleStatus(orderStatus, aftersaleStatus, orderId);
        //并且订单变成一条售后信息
        Integer type = 0; //售后type表示未收货退款
        MarketAftersale marketAftersale = new MarketAftersale();
        marketAftersale.setAftersaleSn(UUID.randomUUID().toString()); //UUID新增售后编号
        marketAftersale.setOrderId(orderId);
        //获取用户信息
        WxLoginUserData principal = (WxLoginUserData) SecurityUtils.getSubject().getPrincipal();
        Integer userId = principal.getId();
        marketAftersale.setUserId(userId);
        marketAftersale.setType(type);
        //获取订单信息
        WxOrderDetailVo order = wxOrderDao.getOrderDetailByOrderId(orderId);
        Double actualPrice = order.getActualPrice(); //实付金额
        marketAftersale.setAmount(actualPrice);
        marketAftersale.setStatus(1);
        String format = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss").format(System.currentTimeMillis()); //当前时间
        marketAftersale.setAddTime(format);
        marketAftersale.setUpdateTime(format);
        String [] strings = new String[0];
        marketAftersale.setPictures(strings);
        marketAftersale.setDeleted(false);
        wxOrderDao.insertAftersale(marketAftersale);
    }

    /**
     * 删除订单
     * @param orderId
     */
    @Override
    public void deleteOrder(Integer orderId) {
        wxOrderDao.deleteOrder(orderId);
    }

    /**
     * 确认收货
     * @param orderId
     */
    @Override
    public void confirm(Integer orderId) {
        Integer orderStatus = 401;
        wxOrderDao.changeOrderStatus(orderStatus, orderId);
        //更新订单信息
        MarketOrder marketOrder = new MarketOrder();
        marketOrder.setId(orderId);
        marketOrder.setConfirmTime(new Date(System.currentTimeMillis()));
        marketOrder.setUpdateTime(new Date(System.currentTimeMillis()));
        wxOrderDao.updateOrderValues(marketOrder);
    }

    /**
     * 取消订单或者退款等操作之后,将订单中商品返回到库存
     * @param orderGoods
     */
    @Override
    public void returnGoods(List<WxOrderDetailGoodsVo> orderGoods) {
        for (WxOrderDetailGoodsVo orderGood : orderGoods) {
            Integer productId = orderGood.getProductId();
            Integer number = orderGood.getNumber();
            wxOrderDao.returnGoods(productId, number);
        }
    }


    /**
     * 收货后提交订单售后申请
     * @param marketAftersale: 售后信息
     */
    @Override
    public void submitAftersale(MarketAftersale marketAftersale) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        marketAftersale.setAddTime(simpleDateFormat.format(System.currentTimeMillis())); //当前时间
        marketAftersale.setUpdateTime(simpleDateFormat.format(System.currentTimeMillis())); //当前时间
        marketAftersale.setAftersaleSn(UUID.randomUUID().toString()); //使用UUID随机生成售后编号

        //获取用户信息
        WxLoginUserData principal = (WxLoginUserData) SecurityUtils.getSubject().getPrincipal();
        Integer userId = principal.getId();
        marketAftersale.setUserId(userId);
        marketAftersale.setStatus(1); //status为1表示用户已申请
        wxOrderDao.insertAftersale(marketAftersale);


    }

    /**
     * 提交评价内容
     * @param comment
     * @param commentValue
     */
    @Override
    public void comment(Comment comment, CommentSession commentValue) {
        comment.setValueId(0); //valueId 不知道是什么的东西
        comment.setType((byte) 0); //type为0 表示是商品评论
        //获取用户信息
        WxLoginUserData principal = (WxLoginUserData) SecurityUtils.getSubject().getPrincipal();
        Integer userId = principal.getId();
        comment.setUserId(userId);
        comment.setAddTime(new Date(System.currentTimeMillis()));
        comment.setUpdateTime(new Date(System.currentTimeMillis()));
        wxOrderDao.insertComment(comment);

        //将评论id插入orderGoods表中
        wxOrderDao.insertCommentIdIntoOrderGoods(comment.getId(), commentValue.getGoodsId());
        //修改订单待评价商品数
        wxOrderDao.setComments(commentValue.getOrderId());
        //查询订单待评价数
        int comments = wxOrderDao.getComments(commentValue.getOrderId());
        //修改订单状态为已评价501
        if (comments == 0){
            int orderStatus = 501;
            wxOrderDao.changeOrderStatus(orderStatus, commentValue.getOrderId());
        }
    }

    /**
     * 订单付款
     * @param orderId
     */
    @Override
    public void prepay(Integer orderId) {
        MarketOrder marketOrder = new MarketOrder();
        //封装参数
        marketOrder.setId(orderId); //订单id
        marketOrder.setPayId(UUID.randomUUID().toString()); //UUID随机生成微信付款编号
        marketOrder.setPayTime(new Date(System.currentTimeMillis())); //付款时间当前时间
        marketOrder.setUpdateTime(new Date(System.currentTimeMillis())); //订单更新时间
        wxOrderDao.updateOrderValues(marketOrder); //更新订单信息
        Integer orderStatus = 201;
        wxOrderDao.changeOrderStatus(orderStatus, orderId);
    }

    /**
     * 新增订单表
     * @param wxOrderSubmitBo
     */
    @Override
    public WxOrderSubmitVo createOrder(WxOrderSubmitBo wxOrderSubmitBo) {


        //创建订单，插入订单表
        //获取用户ID
        WxLoginUserData principal = (WxLoginUserData) SecurityUtils.getSubject().getPrincipal();
        Integer userId = principal.getId();
        //生成订单编号
        String order_sn = userId.hashCode()+ "" +System.currentTimeMillis() ;
        //订单状态 101 待付款
        Integer orderStatus = 101;
        //售后状态 0 ,可申请
        Integer aftersaleStatus = 0;
        //获取收货人信息
        //根据addressid取出地址详情
        WXAddressDetailVo wxAddressDetailVo = wxAddressMapper.selectAddressDetail(wxOrderSubmitBo.getAddressId());
        //收件人名称
        String consignee = wxAddressDetailVo.getName();
        //收货人手机号
        String mobile = wxAddressDetailVo.getTel();
        //收货人具体地址
        String address = wxAddressDetailVo.getCounty() + " " + wxAddressDetailVo.getProvince() + " " +
                wxAddressDetailVo.getCity() + " " + wxAddressDetailVo.getAddressDetail();
        //用户订单留言
        String message = wxOrderSubmitBo.getMessage();

        //商品总费用
        List<Cart> checkedGoodsListDTO = wxCartMapper.selectAllCartInfo(userId, wxOrderSubmitBo.getCartId());

        BigDecimal couponPrice = new BigDecimal(0);
        BigDecimal grouponPrice = new BigDecimal(0);

        BigDecimal freightPrice = new BigDecimal(0);
        Integer couponId = wxOrderSubmitBo.getCouponId();
        Integer userCouponId = wxOrderSubmitBo.getUserCouponId();
        Integer availableCouponLength = 0;
        Integer grouponRulesId = wxOrderSubmitBo.getGrouponRulesId();
        // 更新用户优惠券状态
        userCouponDao.deleteUserCoupon(userCouponId);
        if (couponId > 0 && userCouponId > 0) {
            //通过couponId 选出 couponPrice
            couponPrice = wxCartMapper.selectDiscountFromMarketCouponByCouponId(couponId);
            //通过userCouponId设置coupon为已使用
            wxCartMapper.updateCouponStatusByUserCouponId(userCouponId);
            //通过userId选出还有几张coupon可以用 -- availableCouponLength
            availableCouponLength = wxCartMapper.selectCountCouponByUserId(userId);

        }

        if (grouponRulesId > 0) {
            //通过groupRulesId 选出groupPrice
            grouponPrice = wxCartMapper.selectDiscountFromMarketGrouponRulesByGroupRulesId(grouponRulesId);
        }

        Integer cartGoodsSize = checkedGoodsListDTO.size();
        BigDecimal goodsTotalPrice = new BigDecimal(0);
        MathContext mathContext = new MathContext(2);

        for (Cart cart : checkedGoodsListDTO) {
            BigDecimal multiply = cart.getPrice().multiply(new BigDecimal(cart.getNumber()), mathContext);
            goodsTotalPrice = goodsTotalPrice.add(multiply);

        }
        BigDecimal actualPrice = goodsTotalPrice.subtract(couponPrice).subtract(grouponPrice);
        BigDecimal orderTotalPrice = actualPrice;
        BigDecimal integralPrice = new BigDecimal(0);

        Date addTime = DateUtils.getNowDate();
        int waitTime = 30; //minites
        Date endTime = DateUtils.getFutureDate(waitTime*60*1000);


        MarketOrder orderInsertBean = null;
        try {
            orderInsertBean = BeanCreateUtils.createBean(MarketOrder.class,
                    null,
                    userId,
                    order_sn,
                    orderStatus,
                    aftersaleStatus,
                    consignee,
                    mobile,
                    address,
                    message,
                    goodsTotalPrice,
                    freightPrice,
                    couponPrice,
                    integralPrice,
                    grouponPrice,
                    orderTotalPrice,
                    actualPrice,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    null,
                    cartGoodsSize,
                    endTime,
                    addTime,
                    addTime,
                    false);
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        wxOrderDao.insertNewOrder(orderInsertBean);

        //将订单中的商品插入orderGoods表
        Integer orderId = orderInsertBean.getId();
        //插入market_order_goods表

        List<OrderGoods> orderGoodsList = new ArrayList<>();
        Date nowDateTime = DateUtils.getNowDate();
        for (Cart cart : checkedGoodsListDTO) {
            OrderGoods orderGoodsBean = null;
            try {
                orderGoodsBean = BeanCreateUtils.createBean(OrderGoods.class, null, orderId, cart.getGoodsId(), cart.getGoodsName(), cart.getGoodsSn(), cart.getProductId(), cart.getNumber(), cart.getPrice(), cart.getSpecifications(), cart.getPicUrl(), null, nowDateTime, nowDateTime, false);
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }
            orderGoodsList.add(orderGoodsBean);
        }

        wxOrderDao.insertMarketOrderGoodsBatch(orderGoodsList);

        //删除购物车中选中的商品
        wxCartMapper.updateCartAfterCheckOut(userId,wxOrderSubmitBo.getCartId());

        WxOrderSubmitVo wxOrderSubmitVo = new WxOrderSubmitVo();
        wxOrderSubmitVo.setOrderId(orderInsertBean.getId());
        wxOrderSubmitVo.setGrouponLinkId(wxOrderSubmitBo.getGrouponLinkId());


        return wxOrderSubmitVo;
    }

    /**
     * 小程序个人中心获取售后信息显示
     * @param status: 售后状态
     * @param page: 当前页数
     * @param limit: 单页限制
     * @return
     */
    @Override
    public WxAftersaleListVo getAftersaleListInfo(Integer status, Integer page, Integer limit) {
        //开启分页
        PageHelper.startPage(page, limit);
        //获取用户ID
        WxLoginUserData principal = (WxLoginUserData) SecurityUtils.getSubject().getPrincipal();
        Integer userId = principal.getId();
        //获取该用户所有处于售后状态下的订单,订单包含商品和售后信息
        List<Integer> orderIds = wxOrderDao.getAftersaleOrders(userId, status);
        LinkedList<WxAftersaleVo> wxAftersaleVos = new LinkedList<>();
        for (Integer orderId : orderIds) {
            WxAftersaleVo wxAftersaleVo = new WxAftersaleVo();
            //通过orderId查询goods
            List<WxOrderDetailGoodsVo> orderGoods = this.getWxOrderDetailInfo(orderId).getOrderGoods();
            //通过orderId查询aftersale信息
            MarketAftersale aftersale = wxOrderDao.getAftersale(orderId, status);
            wxAftersaleVo.setGoodsList(orderGoods);
            wxAftersaleVo.setAftersale(aftersale);
            wxAftersaleVos.add(wxAftersaleVo);
        }
        WxAftersaleListVo wxAftersaleListVo = new WxAftersaleListVo();
        wxAftersaleListVo.setList(wxAftersaleVos);
        //获取分页信息
        PageInfo<WxAftersaleVo> pageInfo = new PageInfo<>(wxAftersaleVos);
        wxAftersaleListVo.setTotal((int) pageInfo.getTotal());
        wxAftersaleListVo.setPages(pageInfo.getPages());
        wxAftersaleListVo.setPage(page);
        wxAftersaleListVo.setLimit(limit);
        return wxAftersaleListVo;
    }
}
